package com.heima.user.service.impl;

import cn.hutool.core.lang.UUID;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.common.constants.UserAuthConstant;
import com.heima.feign.api.WemediaFeignClient;
import com.heima.minio.MinIOTemplate;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dto.AuthDto;
import com.heima.model.user.entity.ApUser;
import com.heima.model.user.entity.ApUserRealname;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.user.dao.ApUserDao;
import com.heima.user.dao.ApUserRealnameDao;
import com.heima.user.service.ApUserRealnameService;
import com.heima.user.util.AppUserThreadLocalUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * APP实名认证信息表(ApUserRealname)表服务实现类
 *
 * @author makejava
 * @since 2022-04-23 08:54:23
 */
@Service("apUserRealnameService")
public class ApUserRealnameServiceImpl implements ApUserRealnameService {
    @Resource
    private ApUserRealnameDao apUserRealnameDao;

    @Resource
    private MinIOTemplate minIOTemplate;

    @Resource
    private ApUserDao apUserDao;

    @Resource
    private WemediaFeignClient wemediaFeignClient;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ApUserRealname queryById(Long id) {
        return this.apUserRealnameDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<ApUserRealname> queryAllByLimit(int offset, int limit) {
        return this.apUserRealnameDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param apUserRealname 实例对象
     * @return 实例对象
     */
    @Override
    public ApUserRealname insert(ApUserRealname apUserRealname) {
        this.apUserRealnameDao.insert(apUserRealname);
        return apUserRealname;
    }

    /**
     * 修改数据
     *
     * @param apUserRealname 实例对象
     * @return 实例对象
     */
    @Override
    public ApUserRealname update(ApUserRealname apUserRealname) {
        this.apUserRealnameDao.update(apUserRealname);
        return this.queryById(apUserRealname.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.apUserRealnameDao.deleteById(id) > 0;
    }

    @Override
    public ResponseResult submit(MultipartFile font_image, MultipartFile back_image, MultipartFile hold_image, MultipartFile live_image, String name, String idno) {
        //1. 参数校验
        if (StringUtils.isEmpty(name) || StringUtils.isEmpty(idno)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        ApUserRealname apUserRealname = new ApUserRealname();
        apUserRealname.setName(name);
        apUserRealname.setIdno(idno);
        apUserRealname.setUserId(AppUserThreadLocalUtil.get().getId());
        apUserRealname.setStatus(1);
        apUserRealname.setCreatedTime(new Date());
        apUserRealname.setUpdatedTime(new Date());

        //2. 图片上传到MinIo
        try {
            if (!font_image.isEmpty()) {
                String filename = font_image.getOriginalFilename();
                String suffix = filename.substring(filename.lastIndexOf("."));

                filename = UUID.randomUUID().toString() + suffix;
                String font_image_url = minIOTemplate.uploadImgFile("", filename, font_image.getInputStream());
                apUserRealname.setFontImage(font_image_url);
            }

            if (!back_image.isEmpty()) {
                String filename = back_image.getOriginalFilename();
                String suffix = filename.substring(filename.lastIndexOf("."));

                filename = UUID.randomUUID().toString() + suffix;
                String back_image_url = minIOTemplate.uploadImgFile("", filename, back_image.getInputStream());
                apUserRealname.setBackImage(back_image_url);
            }

            if (!hold_image.isEmpty()) {
                String filename = hold_image.getOriginalFilename();
                String suffix = filename.substring(filename.lastIndexOf("."));

                filename = UUID.randomUUID().toString() + suffix;
                String hold_image_url = minIOTemplate.uploadImgFile("", filename, hold_image.getInputStream());
                apUserRealname.setHoldImage(hold_image_url);
            }

            if (!live_image.isEmpty()) {
                String filename = live_image.getOriginalFilename();
                String suffix = filename.substring(filename.lastIndexOf("."));

                filename = UUID.randomUUID().toString() + suffix;
                String live_image_url = minIOTemplate.uploadImgFile("", filename, live_image.getInputStream());
                apUserRealname.setLiveImage(live_image_url);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVICE_BUSY);
        }

        //3. 封装数据保存
        apUserRealnameDao.insert(apUserRealname);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult list(AuthDto dto) {
        //1. 校验参数
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        //2. 封装查询条件
        ApUserRealname queryParam = new ApUserRealname();
        if (dto.getStatus() != null) {
            queryParam.setStatus(dto.getStatus());
        }
        //3. 开启分页, 执行查询
        PageHelper.startPage(dto.getPage(), dto.getSize());
        Page<ApUserRealname> page = apUserRealnameDao.queryAll(queryParam);

        //4. 封装数据返回
        ResponseResult result = new PageResponseResult(page.getPageNum(), page.getPageSize(), (int) page.getTotal());
        result.setData(page.getResult());

        return result;
    }

    @Override
    @GlobalTransactional
    public ResponseResult auth(Long id, int status, String msg) {
        //1. 校验参数  id存不存在  id对应的数据是否存在
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        ApUserRealname apUserRealname = apUserRealnameDao.queryById(id);
        if (apUserRealname == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //2. 判断是审核通过还是审核失败
        //2.1 审核失败 ----- 修改数据库状态以及失败原因
        if (status == UserAuthConstant.AUTH_FAIL) {
            apUserRealname.setStatus(status);
            apUserRealname.setReason(msg);
            apUserRealname.setUpdatedTime(new Date());
            apUserRealnameDao.update(apUserRealname);
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }

        //2.2 审核通过 ---- 修改数据库状态 , 调用自媒体服务开通自媒体账号
        apUserRealname.setStatus(status);
        apUserRealname.setUpdatedTime(new Date());
        apUserRealnameDao.update(apUserRealname);

        //创建自媒体用户
        createWmUser(apUserRealname.getUserId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    private void createWmUser(Long userId) {
        if (userId == null) {
            throw new RuntimeException("APP用户信息不存在,缺少参数");
        }
        //1. 根据用户id查询用户信息
        ApUser apUser = apUserDao.queryById(userId);
        if (apUser == null) {
            throw new RuntimeException("APP用户信息不存在,缺少参数");
        }

        //2. 封装自媒体用户数据
        WmUser wmUser = new WmUser();
        BeanUtils.copyProperties(apUser, wmUser);
        // avatar
        wmUser.setAvatar(apUser.getImage());

        //3. 调用远程Feign接口创建自媒体用户

        //使用Feign发起http请求的时候, 将线程中的用户ID取出来, 放入到Feign的请求中
        //可以使用Feign客户端提供的拦截器实现 ---- 拦截器在Feign请求发出之前执行
        wemediaFeignClient.saveWmUser(wmUser);

        int i = 10 / 0;
    }
}
